package com.lerays.spider.sougou.server;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

import org.lionsoul.websnail.json.JSONArray;
import org.lionsoul.websnail.json.JSONObject;

/**
 * client socket bean. <br />
 * class for the server to manage the clients.
 * 
 * @author chenxin<chenxin619315@gmai.com>
 */
public class ClientBean implements Runnable
{
	private SpiderServer spiderServer = null;
	private Socket socket = null;
	
	/**
	 * data input/output stream
	 */
	private DataInputStream dis = null;
	private DataOutputStream dos = null;
	
	/**
	 * construct method to create a new ClientBean
	 * 
	 * @param	spiderServer
	 * @param	Socket
	 * @throws	IOException
	 */
	public ClientBean( SpiderServer spiderServer, Socket socket ) throws IOException
	{
		this.spiderServer = spiderServer;
		this.socket = socket;
		
		//initialize the input/output stream
		dis = new DataInputStream(socket.getInputStream());
		dos = new DataOutputStream(socket.getOutputStream());
	}

	@Override
	public void run() 
	{
		try {
			//1. get the length of the json command
			int cmdlength = dis.readInt();
			if ( cmdlength <= 0 || cmdlength > 450 )
			{
				throw new IOException("Error: Invalid remote command");
			}
			
			//2. get the json string
			int length = 0;
			byte[] buff = new byte[cmdlength];
			
			while ( length < cmdlength ) {
				int readsize = dis.read(buff, length, cmdlength - length);
				if ( readsize > 0 ) length += readsize;
				else break;
			}
			
			//3. parse and execute the command
			String cmd = new String(buff);
			JSONObject json = new JSONObject(cmd);
			if ( ! json.has("cmd") )
			{
				throw new IOException("Error: Invalid command missing \"cmd\" command array");
			}
			
			JSONArray commands = json.getJSONArray("cmd");
			String ret = spiderServer.getCommandExecutor().execute(commands);
			
			//4. write the execute returning result
			byte[] bys = ret.getBytes("UTF-8");
			dos.writeInt(bys.length);
			dos.write(bys);
			dos.flush();
			
			//5. close the socket
			socket.close();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			//5. close the socket
			try {socket.close();} catch (IOException e) {}
		}
	}

	/**
	 * close client bean - mostly close the socket
	 *  
	 * @throws IOException 
	 */
	public void close() throws IOException
	{
		socket.close();
	}
}
